﻿//场景模拟：厨师炒好菜后通知服务员端上桌
//厨师线程：炒菜，炒完后设置 ready = true 并通知服务员。
//服务员线程：等待菜炒好（ready == true），然后执行上菜动作。
#include <iostream>                  // 引入标准输入输出库，用于打印信息
#include <thread>                   // 引入多线程库 std::thread
#include <mutex>                    // 引入互斥锁库 std::mutex
#include <condition_variable>       // 引入条件变量库 std::condition_variable
#include <chrono>                   // 引入时间库，用于 sleep_for 等时间操作
#include <Windows.h>                // Windows 专用，用于设置控制台编码防止中文乱码
// 全局变量与同步机制定义
std::mutex mtx;                     // 互斥锁，用于保护共享变量 dish_ready 的访问
std::condition_variable cv;        // 条件变量，用于实现线程之间的等待和通知机制
bool dish_ready = false;           // 表示“菜是否炒好”的共享标志变量，初始为 false
// 服务员线程函数：等待炒菜完成后上菜
void waiter() {
    std::unique_lock<std::mutex> lock(mtx);       // 获取互斥锁，进入临界区（使用 unique_lock 是为了支持条件变量的 wait）
    std::cout << "服务员：等待厨师炒菜...\n";       // 输出提示信息，表示正在等待菜做好
    // 使用条件变量等待，当 dish_ready == true 时才会继续执行
    // 如果 dish_ready 还未为 true，则 wait 将当前线程挂起，并释放锁
    // 一旦收到 notify_one 通知，线程会重新获取锁并判断 lambda 条件是否成立
    cv.wait(lock, [] { return dish_ready; });
    // 被唤醒后且 dish_ready == true，则执行上菜操作
    std::cout << "服务员：收到通知，开始上菜！\n";
}
// 厨师线程函数：模拟炒菜并通知服务员
void chef() {
    std::this_thread::sleep_for(std::chrono::seconds(2)); // 模拟炒菜过程，睡眠 2 秒
    std::lock_guard<std::mutex> lock(mtx);   // 加锁临界区，准备修改共享变量 dish_ready
    std::cout << "厨师：菜炒好了！\n";         // 输出提示信息，表示炒菜完成
    dish_ready = true;                       // 将 dish_ready 设置为 true，表示菜已炒好
    cv.notify_one();                         // 通知一个等待中的线程（服务员）可以继续执行
}
// 主函数入口
int main() {
    SetConsoleOutputCP(65001);              // 设置 Windows 控制台编码为 UTF-8，防止中文输出乱码
    std::thread t1(waiter);                 // 启动服务员线程，执行 waiter 函数
    std::thread t2(chef);                   // 启动厨师线程，执行 chef 函数
    t1.join();                              // 主线程等待服务员线程结束
    t2.join();                              // 主线程等待厨师线程结束
    std::cout << "流程结束：菜已经端上桌。\n"; // 最后输出提示信息，表示流程已完成
    return 0;                               // 返回 0，程序正常结束
}

